﻿using System;
using System.Net;
using T0yK4T.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using T0yK4T.Tools;

namespace ToyChat
{
    /// <summary>
    /// This interface describes a client for ToyChat
    /// </summary>
    public interface IClient
    {
        /// <summary>
        /// Called from a <see cref="ToyChat.Client.IAuthenticationModule"/> when the user has logged succesfully and the server has sent it's type aliases
        /// </summary>
        /// <param name="aliases">The aliases that were supplied by the server</param>
        void OnAuthenticated(AliasSpecifier aliases);

        /// <summary>
        /// Gets a reference to the userinterface of the client
        /// </summary>
        IUserInterface UI { get; }

        /// <summary>
        /// Sends the specified packet to the server
        /// </summary>
        /// <param name="packet">The packet to send</param>
        void Send(Packet packet);

        /// <summary>
        /// Gets the nametable that represents the current state of the internal TypeID to name map
        /// </summary>
        Dictionary<string, uint> IDMap { get; }

        /// <summary>
        /// Gets a value indicating how many bytes the client has sent (in total)
        /// </summary>
        ulong TotalBytesSent { get; }

        /// <summary>
        /// Gets a value indicating how many bytes the client has received (in total)
        /// </summary>
        ulong TotalBytesReceived { get; }

        /// <summary>
        /// This event is fired when the client has been disconnected
        /// </summary>
        event ClientDisconnectedHandler Disconnected;

        /// <summary>
        /// This event is fired whenever the client has been connected
        /// </summary>
        event ClientConnectedHandler Connected;

        /// <summary>
        /// If connected, will disconnect the client
        /// </summary>
        void Disconnect();

        /// <summary>
        /// Attempts to connect to the remote endpoint specified in <paramref name="settings"/> with the informations specified in <paramref name="settings"/>
        /// </summary>
        /// <param name="settings">The <see cref="IConnectionSettings"/> to use when connecting</param>
        /// <returns>True if succesful, otherwise false</returns>
        bool ConnectTo(IConnectionSettings settings);

        /// <summary>
        /// Gets a value indicating wether or not the client considers itself as being connected to a server
        /// </summary>
        bool IsConnected { get; }

        /// <summary>
        /// Gets the Remote Endpoint of the underlying connection (if connected)
        /// </summary>
        IPEndPoint RemoteEndpoint { get; }
    }
}
